﻿using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

using EnvDTE;
using EnvDTE80;

namespace ReSearcher
{
    class ReSearchLogic
    {
        private DTE2 _dte;
        internal const string LocationSelection = "Selected Text";
        internal const string LocationThisDoc = "This Document";
        internal const string LocationAllOpen = "All Open Documents";
        internal const string LocationSolution = "Entire Solution";
        internal const string LocationProject = "This Project";

        System.Collections.Generic.LinkedList<Document> _documents = new System.Collections.Generic.LinkedList<Document>();

        internal ReSearchLogic(DTE2 dte)
        {
            _dte = dte;
        }

        internal void Search(Regex pattern, string location, bool keepSearching)
        {
            TextDocument doc;
            int direction = (pattern.Options & RegexOptions.RightToLeft) == RegexOptions.RightToLeft ? -1 : 1;

            switch (location)
            {
                case LocationThisDoc:
                case LocationAllOpen:

                    if (_dte.ActiveDocument == null)
                        return;

                    doc = (TextDocument)_dte.ActiveDocument.Object("TextDocument");

                    EditPoint p;
                    string text;

                    p = doc.CreateEditPoint();
                    text = p.GetText(doc.EndPoint).Replace("\r\n", "\n");
                    // = (pattern.Options & RegexOptions.RightToLeft) == RegexOptions.RightToLeft;

                    int startAt = -1;//(up ? Selection.AnchorPoint.AbsoluteCharOffset : Selection.ActivePoint.AbsoluteCharOffset) - 1;
                    Match m = pattern.Match(text, startAt);

                    if (!m.Success)
                    {
                        if (keepSearching)
                        {
                            if (true)
                                Selection.MoveToPoint(doc.EndPoint);
                            else
                                Selection.MoveToPoint(doc.StartPoint);

                            Search(pattern, location, false);
                        }
                        break;
                    }

                    Selection.MoveToAbsoluteOffset(m.Index + 1);
                    Selection.MoveToAbsoluteOffset(m.Index + 1 + m.Length, true);

                    break;

                case LocationAllOpen:

                    //foreach (Document doc in _dte.Documents)
                    //{

                    //}
                    break;
            }

            bool loopedBack = false;

            while (!loopedBack)
            {
                //FindResult 
            }
        }

        private FindResult FindAndSelectInDoc(TextDocument doc, Regex pattern, int start, int direction)
        {
            EditPoint p;
            string text;

            p = doc.CreateEditPoint();
            text = p.GetText(doc.EndPoint).Replace("\r\n", "\n");
            bool up = (pattern.Options & RegexOptions.RightToLeft) == RegexOptions.RightToLeft;

            Match m = pattern.Match(text, start);

            if (!m.Success)
                return new FindResult();

            Selection.MoveToAbsoluteOffset(m.Index + 1);
            Selection.MoveToAbsoluteOffset(m.Index + 1 + m.Length, true);

            return new FindResult(string.Empty, m.Value, m.Index, m.Length);
        }

        private void PrintCode()
        {
            try
            {
                foreach (Project project in _dte.Solution.Projects)
                {
                    ParseProjectItems(project.ProjectItems);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
        }

        private void ParseProjectItems(ProjectItems projectItems)
        {
            if (projectItems == null)
            {
                return;
            }

            foreach (ProjectItem pItem in projectItems)
            {
                Debug.WriteLine("Project item \"{0}\" in project \"{1}{2}\" ", pItem.Name, pItem.ContainingProject.Name, pItem.ContainingProject.FullName);
                ParseProjectItem(pItem);
            }
        }

        private void ParseProjectItem(ProjectItem pItem)
        {
            if (File.Exists(ProjectItemFullName(pItem)))
                Debug.WriteLine("Project full name \"{0}\"", ProjectItemFullName(pItem));

            if (pItem.ProjectItems != null)
                ParseProjectItems(pItem.ProjectItems);
        }

        private string ProjectItemText(ProjectItem item)
        {
            TextDocument editDoc = (TextDocument)item.Document.Object("TextDocument");
            EditPoint objEditPt = editDoc.CreateEditPoint();
            objEditPt.StartOfDocument();


            return null;
        }

        private string ProjectItemFullName(ProjectItem pItem)
        {
            return pItem.FileCount > 0 ? pItem.get_FileNames(1) : "";
        }

        private string ActiveDocumentPath
        {
            get
            {
                if (_dte != null && _dte.ActiveDocument != null)
                {
                    return _dte.ActiveDocument.FullName;
                }
                else
                {
                    return null;
                }
            }
        }

        internal TextSelection Selection
        {
            get
            {
                if (_dte.ActiveDocument == null)
                    return null;

                return (TextSelection)_dte.ActiveDocument.Selection;
            }
        }
    }
}
